import { Dep } from './Dep.js'
/**
 Observer类
	1. 数据劫持,把 $data 中的成员转换成 getter/setter
	2. 初始化Dep
	3. 在 getter中添加依赖watcher
	4. 在setter中通知更新页面
 */
export class Observer {
	constructor(data) {
		this.walk(data)
		this.dep = new Dep()// 创建 dep 对象收集依赖
	}
	//1. 判断数据是否是对象，如果不是对象返回 2. 如果是对象，遍历对象的所有属性，设置为 getter/setter
	walk(data) {
		if (!data || typeof data !== 'object') {
			return
		}
		// 遍历 data 的所有成员
		Object.keys(data).forEach(key => {
			this.defineReactive(data, key, data[key])
		})
	}
	// 定义响应式成员
	defineReactive(data, key, val) {
		const that = this
		// 如果 val 是对象，继续设置它下面的成员为响应式数据
		this.walk(val)
		Object.defineProperty(data, key, {
			configurable: true,
			enumerable: true,
			get() {
				Dep.target && that.dep.addSub(Dep.target)// get 的过程中收集依赖,添加Watcher观察者
				return val
			},
			set(newValue) {
				if (newValue === val) {
					return
				}
				that.walk(newValue)// 如果 newValue 是对象，设置 newValue 的成员为响应式
				val = newValue
				// 当数据变化之后，发送通知
				that.dep.notify()
			},
		})
	}
}
